package cc.zy.base.hr.controller;

import cc.zy.base.common.controller.BaseController;
import cc.zy.base.common.entity.FebsResponse;
import cc.zy.base.common.entity.QueryRequest;
import cc.zy.base.common.utils.FebsUtil;
import cc.zy.base.hr.entity.Staff;
import cc.zy.base.hr.entity.StaffSyncLog;
import cc.zy.base.hr.service.IStaffService;
import cc.zy.base.hr.service.IStaffSyncLogService;
import cn.hutool.log.dialect.commons.ApacheCommonsLog;
import cn.hutool.log.level.DebugLog;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.extern.slf4j.XSlf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
import me.chanjar.weixin.cp.bean.WxCpUser;
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author ljy
 * @time 2022/03/09 10:34:59
 */
@Controller("staffView")
@Slf4j
@Validated
@RequiredArgsConstructor
public class StaffController extends BaseController {

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private final IStaffSyncLogService logService;

    @Autowired
    private final IStaffService staffService;

    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");

    /**
     * 男性性别对应值
     */
    private static Integer GENDER_DATA_MALE;

    /**
     *女性性别对应值
     */
    private static Integer GENDER_DATA_FEMALE;

    /**
     *未知性别对应值
     */
    private static Integer GENDER_DATA_UNKNOWN;

    /**
     *员工已激活状态对应值
     */
    private static Integer STATUS_DATA_ACTIVED;

    /**
     *员工禁用状态对应值
     */
    private static Integer STATUS_DATA_FORBIDDEN;

    /**
     *员工未激活状态对应值
     */
    private static Integer STATUS_DATA_UNACTIVED;

    /**
     *员工已离职对应值
     */
    private static Integer STATUS_DATA_LEFT;

    /**
     *日志同步成功对应值
     */
    private static Integer STATUS_STAFF_SYNC_SUCCESS;

    /**
     *日志同步失败对应值
     */
    private static Integer STATUS_STAFF_SYNC_FAIL;

    /**
     *同步日志自动推送模式对应值
     */
    private static Integer MODE_STAFF_SYNC_AUTO;

    /**
     *同步日志手动同步对应值
     */
    private static Integer MODE_STAFF_SYNC_MANUAL;


    /**
     * 查找员工
     *
     * @param request
     * @param staff
     * @return
     */
    @GetMapping("staff/list")
    @ResponseBody
    public FebsResponse staffList(QueryRequest request, Staff staff,Model model) {
        log.debug("前台传来的对象是：" + staff);
        Map<String, Object> dataTable = getDataTable(staffService.getStaffs(request, staff));
        return new FebsResponse().success().data(dataTable);

    }

    /**
     * 从企业微信拉取员工列表，更新数据库，生成日志
     * @return
     */
    @GetMapping("staff/updateStaff")
    @ResponseBody
    public FebsResponse updateStaff() {
        //获取数据库字典中性别对应的id的值
        getGenderIdAndStatusId();

        try {
            //发送请求，获取员工列表
            List<Staff> staffList = getWeComStaff();

            //将拉取的员工列表和数据库中的员工列表进行对比，若本地存在而企业微信不存在，则删除本地条目
            //将拉取的员工id放入集合
            List<String> WeComUserIdList = new ArrayList<>();
            for (Staff listStaff : staffList) {
                WeComUserIdList.add(listStaff.getUserId());
            }
            //数据库中的员工id集合
            List<String> staffInDatabase = staffService.getAllStaffUserIdList();
            //将两个集合对比
            for (String staffInBase : staffInDatabase) {
                if (!WeComUserIdList.contains(staffInBase)) {
                    staffService.deleteStaffByUserId(staffInBase);
                }
            }
            for (Staff staff : staffList) {
                //将员工表里的性别和字典表中的id保持一致
                switch (staff.getGender()) {
                    case 1 : staff.setGender(GENDER_DATA_MALE); break;
                    case 2 : staff.setGender(GENDER_DATA_FEMALE); break;
                    default : staff.setGender(GENDER_DATA_UNKNOWN); break;
                }
                //将员工表里的员工状态和字典表中的id保持一致
                switch (staff.getStatus()) {
                    case 1: staff.setStatus(STATUS_DATA_ACTIVED); break;
                    case 2: staff.setStatus(STATUS_DATA_FORBIDDEN); break;
                    case 4: staff.setStatus(STATUS_DATA_UNACTIVED); break;
                    default: staff.setStatus(STATUS_DATA_LEFT); break;
                }

                //如果数据库中已存在该员工的信息，则更新；若不存在则新增
                if (staffService.staffExist(staff)) {
                    staffService.updateStaffByUserId(staff);
                } else {
                    staff.setLastModifyDate(new Date());
                    staffService.save(staff);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new FebsResponse().success().data(new Date());
    }

    /**
     * 第一次拉取员工列表时，将字典表中对应的id值查到
     */
    public void getGenderIdAndStatusId() {
        //如果已经查询过，则跳过
        if (GENDER_DATA_MALE != null) {
            return;
        }
        GENDER_DATA_MALE = staffService.getConstantId("男");
        GENDER_DATA_FEMALE = staffService.getConstantId("女");
        GENDER_DATA_UNKNOWN = staffService.getConstantId("未知");
        STATUS_DATA_ACTIVED = staffService.getConstantId("已激活");
        STATUS_DATA_FORBIDDEN = staffService.getConstantId("已禁用");
        STATUS_DATA_UNACTIVED = staffService.getConstantId("未激活");
        STATUS_DATA_LEFT = staffService.getConstantId("退出企业");
        STATUS_STAFF_SYNC_SUCCESS = staffService.getConstantId("同步成功");
        STATUS_STAFF_SYNC_FAIL = staffService.getConstantId("同步失败");
        MODE_STAFF_SYNC_AUTO = staffService.getConstantId("自动推送");
        MODE_STAFF_SYNC_MANUAL = staffService.getConstantId("手动同步");
    }

    /**
     * 发送请求，获得响应，得到响应中的员工列表
     * @return
     */
    public List<Staff> getWeComStaff() {
        List<Staff> staffList = new ArrayList<>();
        PrintStream oldPrintStream = System.out;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        StaffSyncLog staffSyncLog = new StaffSyncLog();
        String filePath = getLogUrl(simpleDateFormat.format(new Date()));
        try {
            System.setOut(new PrintStream(bos));
            WxCpDefaultConfigImpl config = new WxCpDefaultConfigImpl();
            // 设置微信企业号的appid
            config.setCorpId("wwa431d9d8b2604992");
            // 设置微信企业号的app corpSecret
            config.setCorpSecret("DbpsPO9DgrZlJ-P2c5ElvWZXA7IzOgAv6pnNDuehftk");
            config.setAgentId(1000002);
            WxCpServiceImpl wxCpService = new WxCpServiceImpl();
            wxCpService.setWxCpConfigStorage(config);
            //发送请求
            List<WxCpUser> users = wxCpService.getUserService().listByDepartment(1L, true, 0);
            //将查询的用户存入运功实体类里
            for (WxCpUser wxCpUser : users) {
                Staff staff = new Staff();
                String userId = wxCpUser.getUserId();
                staff.setUserId(wxCpUser.getUserId());
                staff.setName(wxCpUser.getName());
                staff.setGender(Integer.valueOf(wxCpUser.getGender().getCode()));
                staff.setPosition(wxCpUser.getPosition());
                staff.setMobile(wxCpUser.getMobile());
                staff.setEmail(wxCpUser.getEmail());
                staff.setThumbAvatar(wxCpUser.getThumbAvatar());
                staff.setAlias(wxCpUser.getAlias());
                staff.setStatus(wxCpUser.getStatus());
                Map<String, String> openid = wxCpService.getUserService().userId2Openid(userId, null);
                staff.setOpenId(openid.get("openid"));
                staffList.add(staff);
            }
            //生成成功同步日志
            staffSyncLog.setSyncMode(MODE_STAFF_SYNC_MANUAL);
            staffSyncLog.setStatus(STATUS_STAFF_SYNC_SUCCESS);
            staffSyncLog.setSyncTime(new Date());
            staffSyncLog.setSyncUrl(filePath);
            logService.createStaffSyncLog(staffSyncLog);
        } catch (WxErrorException e) {
            e.printStackTrace();
            //生成同步失败日志
            staffSyncLog.setSyncMode(MODE_STAFF_SYNC_MANUAL);
            staffSyncLog.setStatus(STATUS_STAFF_SYNC_FAIL);
            staffSyncLog.setSyncTime(new Date());
            staffSyncLog.setSyncUrl(filePath);
            logService.createStaffSyncLog(staffSyncLog);
        } finally {
            System.setOut(oldPrintStream);
        }
        //将日志写入文件
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(filePath);
            fileOutputStream.write(bos.toByteArray());
            //关闭连接
            fileOutputStream.close();
            bos.close();
            oldPrintStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return staffList;
    }

    /**
     * 生成日志的路径及文件名
     * @param fileName
     * @return
     */
    String getLogUrl(String fileName){
        return "src/main/resources/logs/"+fileName+".log";
    }

    /**
     * 给指定用户发送消息
     * @param userId
     * @return
     */
    @GetMapping("staff/sendMsg/{userId}")
    @ResponseBody
    public FebsResponse sendMsg(@PathVariable String userId){
        try {
            WxCpDefaultConfigImpl config = new WxCpDefaultConfigImpl();
            // 设置微信企业号的appid
            config.setCorpId("wwa431d9d8b2604992");
            // 设置微信企业号的app corpSecret
            config.setCorpSecret("DbpsPO9DgrZlJ-P2c5ElvWZXA7IzOgAv6pnNDuehftk");
            // 设置微信企业号应用ID
            config.setAgentId(1000002);

            WxCpServiceImpl wxCpService = new WxCpServiceImpl();
            wxCpService.setWxCpConfigStorage(config);
            WxCpMessage wxCpMessage = WxCpMessage
                    .TEXT()
                    // 企业号应用ID
                    .agentId(1000002)
                    .toUser(userId)
                    .content(FebsUtil.getCurrentUser().getUserId()+"")
                    .build();
            wxCpService.getMessageService().send(wxCpMessage);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new FebsResponse().success();
    }


}
